<?php

namespace Condistelec\MainBundle\Controller;

use Condistelec\MainBundle\Entity\Partida;
use Condistelec\MainBundle\Entity\Serie;
use Condistelec\MainBundle\Entity\Pregunta;
use Condistelec\MainBundle\Entity\Opcion;
use Condistelec\MainBundle\Entity\ResultadoSerie;
use Condistelec\MainBundle\Entity\Correccion;
use Condistelec\MainBundle\Entity\Respuesta;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
use Symfony\Component\Form\FormError;
use Symfony\Component\Form\Forms;
use JMS\SecurityExtraBundle\Annotation\Secure;

class SerieController extends Controller
{
	/**
	 * @Route("/cuestionario/{idUsuario}", name = "_cond_app_cuestionario")
	 * @Secure(roles="ROLE_USER")
	 * @Template()
	 */
	public function cuestionarioAction($idUsuario)
	{
		$partida = null;
		$serie = null;
		$preguntas = null;
		$usuario = null;

		$em = $this->getDoctrine()->getEntityManager();

		if($idUsuario != null) {
			$partida = $em->getRepository('CondistelecMainBundle:Partida')->findOneBy(array('usuario' => $idUsuario));
			//die(var_dump($partida));
			$serie = $em->getRepository('CondistelecMainBundle:Serie')->findOneBy(array('numero' => $partida->getSerieActual()));
			if($serie->getEsRondaFinal()){
				return $this->redirect($this->generateUrl('_cond_app_usr_final'));
			}
			$preguntas = $em->getRepository('CondistelecMainBundle:Pregunta')->findBy(array('serie' => $serie->getIdSerie()));
		}

		$form = $this->buildFormCuestionario($preguntas);

		if ($this->getRequest()->getMethod() === 'POST') {
			$form->handleRequest($this->getRequest());
			if ($form->isValid()) {
				$data = $form->getData();
				$resultado = $this->getResultadoSerie($preguntas, $data);
				
				$resultadAnterior = $em->getRepository('CondistelecMainBundle:ResultadoSerie')->find($idUsuario);
				if($resultadAnterior != null) {
					$em->remove($resultadAnterior);
					$em->flush();
				}
				$tiempoUsado = $serie->getTiempo() - $data['time'];
				$resultadoActual = new ResultadoSerie();
				$resultadoActual->setIdUsuario($idUsuario);
				$resultadoActual->setResultado($resultado);
				$resultadoActual->setSerie($serie->getIdSerie());
				$resultadoActual->setTiempo($tiempoUsado);
				
				$em->persist($resultadoActual);
				$em->flush();
					
				return $this->redirect($this->generateUrl('_cond_app_cuestionario_respuesta', array('idUsuario' => $idUsuario)));
			}
		}
		$nivel = $this->getLevel($partida->getAciertos());
		return array('form' => $form->createView(), 'serie' => $serie->getNumero(), 'descSerie' => $serie->getTema(), 'aciertosAcumulados' => $partida->getAciertos(), 'nivel' => $nivel);
	}

	/**
	 * 
	 * Enter description here ...
	 * @param unknown_type $preguntas
	 * @param unknown_type $data
	 */
	private function getResultadoSerie($preguntas, $data) {
		$resultado = "";
		foreach ($preguntas as $pregunta) {
			if($resultado != "") {
				$resultado = $resultado . ";";
			}
			$questionId = 'question_' . $pregunta->getIdPregunta();
			$seleccion =  $data[$questionId];
			$opcion = "NaN";
			if($seleccion && $seleccion != "") {
				$opcion = $seleccion;
			}
			$resultado = $resultado . $pregunta->getIdPregunta() . "," . $opcion;
		}
		return $resultado;
	}

	/**
	 * 
	 * Enter description here ...
	 * @param unknown_type $preguntas
	 */
	private function buildFormCuestionario($preguntas)
	{
		$formBuilder = $this->createFormBuilder();
		$em = $this->getDoctrine()->getEntityManager();

		foreach ($preguntas as $pregunta) {
			$opciones = $em->getRepository('CondistelecMainBundle:Opcion')->findBy(array('pregunta' => $pregunta->getIdPregunta()));
			$choices = array();
			foreach ($opciones as $op) {
				$choices[$op->getIdOpcion()] = $op->getValor();
			}
			$questionId = 'question_' . $pregunta->getIdPregunta();
			$formBuilder->add($questionId, 'choice', array(
						'label'  => $pregunta->getDescripcion(),
				        'choices' => $choices,
				        'multiple' => false,
				        'expanded' => true,
				        'attr' => array('class'=>'pregunta'),));
		}
		$formBuilder->add('time', 'hidden', array('data' => '900',));
		$form = $formBuilder->getForm();
		return $form;
	}

	/**
	 * @Route("/cuestionario/respuesta/{idUsuario}", name = "_cond_app_cuestionario_respuesta")
	 * @Secure(roles="ROLE_USER")
	 * @Template()
	 */
	public function respuestaAction($idUsuario)
	{
		$partida = null;
		$serie = null;
		$usuario = null;
		$resultado = null;

		$em = $this->getDoctrine()->getEntityManager();

		if($idUsuario != null) {
			$partida = $em->getRepository('CondistelecMainBundle:Partida')->findOneBy(array('usuario' => $idUsuario));
			$serie = $em->getRepository('CondistelecMainBundle:Serie')->findOneBy(array('numero' => $partida->getSerieActual()));
			$resultado = $em->getRepository('CondistelecMainBundle:ResultadoSerie')->find($idUsuario);
		}

		$correcciones = $this->corregirSerie($resultado);
		
		$contErrores = $this->countErrores($correcciones);
		$contAciertos = sizeof($correcciones) - $contErrores;
		
		$totalErrores = $contErrores + $partida->getErrores();
		$partida->setErrores($totalErrores);

		$totalAciertos = $contAciertos + $partida->getAciertos();
		$partida->setAciertos($totalAciertos);
		
		$partida->setTiempoAcum($partida->getTiempoAcum() + $resultado->getTiempo());

		$proxSerie = $partida->getSerieActual() + 1;
		$partida->setSerieActual($proxSerie);

		$em->remove($resultado);
		$em->persist($partida);
		$em->flush();

		$nivel = $this->getLevel($partida->getAciertos());

		return array('correcciones' => $correcciones, 'serie' => $serie->getNumero(), 'descSerie' => $serie->getTema(), 'contAciertos' => $contAciertos, 'totalAciertos' => $totalAciertos, 'idUsuario' => $idUsuario, 'nivel' => $nivel);
	}
	
	private function countErrores($correcciones)
	{
		$errores = 0;
		foreach ($correcciones as $c) {
			if($c->getCorrecta() != 1) {
				$errores++;
			}
		}
		return $errores;
	}
	
	private function corregirSerie($resultado)
	{
		$correcciones = array();
		$resultados = explode(';', $resultado->getResultado());
		$em = $this->getDoctrine()->getEntityManager();
		
		foreach ($resultados as $res) {
			list($idPregunta, $idOpcion) = explode(',', $res);
			$pregunta = $em->getRepository('CondistelecMainBundle:Pregunta')->find($idPregunta);
			$opcionUsr = null;

			$correccion = new Correccion();
			if($idOpcion != "NaN") {
				$opcionUsr = $em->getRepository('CondistelecMainBundle:Opcion')->find($idOpcion);
			}

			$correccion->setConsigna($pregunta->getDescripcion());

			if($opcionUsr != null) {
				$correccion->setRespuestaUsuario($opcionUsr->getValor());
			} else {
				$correccion->setRespuestaUsuario("No respondió a esta pregunta.");
			}

			if($opcionUsr != null && $opcionUsr->getEsCorrecta() == 1) {
				$correccion->setCorrecta(1);
			} else {
				$opCorrecta = $em->getRepository('CondistelecMainBundle:Opcion')->findOneBy(array('pregunta' => $idPregunta, 'esCorrecta' => 1));
				$correccion->setCorrecta(0);
				$correccion->setRespuestaCorrecta($opCorrecta->getValor());
			}
			$this->updateRespuesta($pregunta, $correccion->getCorrecta());
			
			$correcciones[$idPregunta] = $correccion;
		}
		return $correcciones;
	}
	
	private function updateRespuesta($pregunta, $esCorrecta) {

		$em = $this->getDoctrine()->getEntityManager();
		$respuesta = $em->getRepository('CondistelecMainBundle:Respuesta')->findOneBy(array('pregunta' => $pregunta->getIdPregunta()));
		if($respuesta == null) {
			$respuesta = new Respuesta();
			$respuesta->setCantErrores(0);
			$respuesta->setCantTotal(0);
			$respuesta->setPregunta($pregunta);
		}
		$respuesta->setCantTotal($respuesta->getCantTotal() + 1);
		if(!$esCorrecta) {
			$respuesta->setCantErrores($respuesta->getCantErrores() + 1);
		}
		$em->persist($respuesta);
		$em->flush();
	}

	private function getLevel($aciertosPartida) {
		if($aciertosPartida >= 0 && $aciertosPartida <= 14) {
			return 'Aprendiz';
		}
		if($aciertosPartida > 14 && $aciertosPartida <= 29) {
			return 'Principiante';
		}
		if($aciertosPartida > 29 && $aciertosPartida <= 44) {
			return 'Medio';
		}
		if($aciertosPartida > 44 && $aciertosPartida <= 59) {
			return 'Avanzado';
		}
		if($aciertosPartida > 59 && $aciertosPartida <= 99) {
			return 'Experto';
		}
		if($aciertosPartida > 99 && $aciertosPartida <= 124) {
			return 'Profesional';
		}
		return 'Profesor';
	}
}
